package com.xiaozhen.blog.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xiaozhen.blog.entity.Blog;
import com.xiaozhen.blog.entity.Type;
import com.xiaozhen.blog.entity.User;
import com.xiaozhen.blog.entity.vo.BlogAndUserVo;
import com.xiaozhen.blog.mapper.BlogMapper;
import com.xiaozhen.blog.mapper.TypeMapper;
import com.xiaozhen.blog.mapper.UserMapper;
import com.xiaozhen.blog.service.BlogService;
import com.xiaozhen.blog.service.LikeService;
import com.xiaozhen.blog.service.TypeService;
import com.xiaozhen.blog.utils.MarkdownUtils;
import org.checkerframework.checker.units.qual.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @create 2023-04-21 14:10
 */
@Service
public class BlogServiceImpl extends ServiceImpl<BlogMapper, Blog> implements BlogService {

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TypeMapper typeMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private LikeService likeService;

    /**
     * 小圳博客分页
     *
     * @param pageParam
     * @return
     */
    public Page<Blog> blogPage(Page<Blog> pageParam) {

        LambdaQueryWrapper<Blog> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Blog::getCreateTime);

        Page<Blog> blogPage = baseMapper.selectPage(pageParam, wrapper);
        List<Blog> records = blogPage.getRecords();
        for (Blog record : records) {
            Type type = typeMapper.selectById(record.getTypeId());
            System.out.println("type = " + type.getName());
            record.setTypeName(type.getName());

            // 获取博客浏览次数
            String redisKey = "uvBlog:blog_" + record.getId();
            record.setViews((Integer) redisTemplate.opsForValue().get(redisKey));

            User user = userMapper.selectById(record.getUserId());
            record.setHeaderUrl(user.getHeaderUrl());
            record.setNickname(user.getNickname());

            // 获取点赞次数
            long entityLikeCount = likeService.findEntityLikeCount(1, record.getId());
            record.setLike(entityLikeCount);

        }
        blogPage.setRecords(records);
        return blogPage;
    }

    /**
     * 小圳博客分页
     *
     * @param pageParam
     * @return
     */
    public Page<Blog> blogPage2(Page<Blog> pageParam) {

        LambdaQueryWrapper<Blog> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(Blog::getUpdateTime);

        Page<Blog> blogPage = baseMapper.selectPage(pageParam, wrapper);

        return blogPage;
    }

    /**
     * 获取最新发布的前 6 篇博客
     *
     * @return
     */
    public List<Blog> newBlog() {
        LambdaQueryWrapper<Blog> blogWrapper = new LambdaQueryWrapper<>();
        blogWrapper.orderByDesc(Blog::getCreateTime);
        blogWrapper.last("limit 0,6");
        List<Blog> blogList = blogMapper.selectList(blogWrapper);
        return blogList;
    }

    /**
     * 通过博客id获取博客详情和博主信息
     * 并将博客的浏览次数 +1
     *
     * @param blogId
     * @return
     */
    public BlogAndUserVo getBlogAndUser(Long blogId) {
        // 通过博客 id 获取博客详情信息
        Blog blog = blogMapper.selectById(blogId);
        if (blog == null) {
            // TODO 全局异常处理
            System.out.println("博客不存在");
            return null;
        }
        // 文章浏览次数 +1
        String redisKey = "uvBlog:blog_" + blog.getId();
        redisTemplate.opsForValue().increment(redisKey);
        // 通过博主 id 查询对应的博主信息
        User user = userMapper.selectById(blog.getUserId());
        // 将博客详情页需要的信息添加到一个集合中
        BlogAndUserVo blogAndUserVo = new BlogAndUserVo();
        BeanUtil.copyProperties(blog, blogAndUserVo);
        BeanUtil.copyProperties(user, blogAndUserVo);


        blogAndUserVo.setBlogId(blogId);
        blogAndUserVo.setViews((Integer) redisTemplate.opsForValue().get(redisKey));
        String content = blogAndUserVo.getContent();
        blogAndUserVo.setContent(MarkdownUtils.markdownToHtmlExtensions(content));

        return blogAndUserVo;
    }

    /**
     * 获取归档中每年对应的博客
     *
     * @return
     */
    @Override
    public Map<String, List<Blog>> archiveBlog() {
        // 查询哪些年有发布博客
        List<String> years = blogMapper.getYears();
        Map<String, List<Blog>> map = new HashMap<>();
        for (String year : years) {
            map.put(year, blogMapper.selectListByYear(year));
        }
        return map;
    }

    /**
     * 搜索返回博客列表
     *
     * @param query
     * @param pageParam
     * @return
     */
    public Page<Blog> search(String query, Page<Blog> pageParam) {
        // 进行模糊查询
        LambdaQueryWrapper<Blog> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Blog::getTitle, query);
        // 进行分页查询
        Page<Blog> blogPage = blogMapper.selectPage(pageParam, wrapper);
        // 返回博客集合
        return blogPage;
    }
}
